逐次処理からの脱出④ 非同期処理と同期処理
Agenda
同期処理
非同期処理
非同期処理が活躍するユースケース
非同期処理の実現方法
まとめ
同期処理
プログラムが記述された通りに上から順番に実行される。
途中のコードの処理時間が長くても、実行が完了するのを待ち続ける。完了するまでは次の処理に進まない。
memo.icon 普段書いてるコードは大抵が同期処理のはず
非同期処理
一部の処理の完了を待たずに別の処理を実行し始めることで、同時に複数の処理を実行する。
思い処理を別のメンバに切り出し、自分は別の作業をするイメージ。
memo.icon 以下の例がめちゃわかりやすい
食器洗いを機械に任せてる間に、自分はお風呂に入ることで、時間短縮が可能になる。
https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F1185431%2F83df265c-15d4-921a-5c05-45da79e75def.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&w=1400&fit=max&s=441b5dbc54efd78b47d3cb5ac86afeda
非同期処理が活躍するユースケース
I/Oや外部API叩く時など、CPU計算と比べて重い処理がある場面
I/Oが入る時、CPUは遊んでる状態になる。
こういうCPUが遊んでる時にCPU処理を進めることで、最終的なゴールまでの高速化を臨める。
ブラウザ処理でAPIが叩かれる際に、利用者の操作を止めないようにする場面
例えば、利用者がフォームを書いて送信ボタンを押したとする。
この時、サーバーに情報を送るためにI/Oが発生するのだが、、、
このI/Oが完了するまでユーザーが何も操作できない状態になるとUXが一気に落ちてしまう。
そうならなように、非同期処理を用いてI/O発生中もユーザが操作可能なようにしておく。
非同期処理の実現方法
1. マルチスレッド/プロセスを利用して並列に実行する方法
重い処理を別スレッドに乗せて、別のコアで実行させてしまうというとてもシンプルな方法。
切り出す処理がCPUバウンドだろうがIOバウンドだろうが関係なく非同期処理にできる。
2. シングルスレッドでイベントループを利用する方法
重い処理をコールバック関数などで登録して、イベントループの仕組みを用いて処理が完了した時に結果を受け取るようにする。
シングルスレッドの枠を出られないことから、CPUバウンドの処理を切り出すのは無意味。
IOバウンド系の処理でしか非同期からの高速化ができないので注意すること。
まとめ
最初から非同期処理で実装しようしなくていいとは思っている。
同期処理でコードを書いてる際に高速化の必要性が出てきたら、非同期処理できる箇所がないか探してみるといい。
基本的にはI/Oバウンドな処理があれば、そこが非同期ポイントである可能性が高い。
マルチスレッド/プロセスを利用するか、イベントループを利用するかは、その時の状況で決めたらいい。Javascriptのような技術的制約なども意思決定に関係してくるだろう。
参考